#include "matrix3x3.h"
#include "vector.h"
#include <cstring>
#include <iostream>
#include <math.h>
#include <sstream>

const float Matrix3x3::identity[9]= {1,0,0,0,1,0,0,0,1};

Matrix3x3::Matrix3x3(){
    memcpy(this->m,identity,sizeof(m));
}

Matrix3x3::~Matrix3x3(){}

Matrix3x3::Matrix3x3(float theta){
	float rotationMatrix [9] ={cos(theta),-sin(theta),0,sin(theta),cos(theta),0,0,0,1};
	memcpy(m,rotationMatrix,sizeof(rotationMatrix));
}

Matrix3x3::Matrix3x3(float dx,float dy){
	float translationMatrix [9] ={1,0,dx,0,1,dy,0,0,1};
	memcpy(m,translationMatrix,sizeof(translationMatrix));
}

Matrix3x3::Matrix3x3(float ex,float ey,bool n){
	float escaleMatrix [9] = {ex,0,0,0,ey,0,0,0,1};
	memcpy(m,escaleMatrix,sizeof(escaleMatrix));
}

Matrix3x3::Matrix3x3(float ax,float ay,float bx,float by){
	float windowViewport[9] = {ax,0,bx,0,ay,by,0,0,1};
	memcpy(m,windowViewport,sizeof(windowViewport));
}

void Matrix3x3::set(unsigned short x,unsigned short y, float val){
    m[x][y]=val;
}

float Matrix3x3::get(unsigned short x,unsigned short y){
    return m[x][y];
}

void Matrix3x3::loadIdentity(){
	memcpy(this->m,identity,sizeof(m));
}

void Matrix3x3::operator*=(Matrix3x3& matrix){
	float aux=0;
	float maux[3][3];
	for (int i=0;i<MATRIX_SIZE;i++){
		for (int j=0;j<MATRIX_SIZE;j++){
			for(int k=0;k<MATRIX_SIZE;k++){
				aux+=matrix.m[k][j]*this->m[i][k];
			}
	        maux[i][j]=aux;
			aux=0;
		}
	}
	memcpy(this->m,maux,sizeof(maux));
}

Vector Matrix3x3::operator*(const Vector& vector)const{
    Vector ans(0,0);
    float aux=0;
    int j;
    for (int i=0;i<3;i++){
        for (j=0;j<3;j++){
            aux+=this->m[i][j]*vector[j];
        }
        ans[i]=aux;
		aux=0;
    }
    return ans;
}

std::string Matrix3x3::toString(){
    std::ostringstream out;
    int j;
    out << "-------";
    for (int i=0;i<3;i++){
    	out << "[";
        for (j=0;j<3;j++){
			out << this->m[i][j] << " , ";
        }
        out << "]\n";
    }
    out << "-------";
    return out.str();
}
